package comman.duke.display 
{
	import comman.duke.*;
	import comman.duke.display.AnimsData;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	
	/**
	 * 
	 * @author jerry.d
	 */
	public class BitmapClip extends Bitmap 
	{
		private static var NUMS:uint = 0;
		private var frameItem:FrameItem;
		
		public function BitmapClip(groupName:String, animName:String, bitmapData:BitmapData=null, pixelSnapping:String="auto", smoothing:Boolean=false) 
		{
			super(bitmapData, pixelSnapping, smoothing);	
			NUMS++;
			this.name = 'bitmapclip' + NUMS;
			this.setup(groupName, animName);
			this.frameItem = new FrameItem(this.name, this.advanceTime);
			this.addEventListener(Event.ADDED_TO_STAGE, onAdded);
			this.addEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
			
		}
		private var groupName:String;
		public var animName:String;
		private var animData:comman.duke.display.AnimsData;
		public function setup(groupName:String, animName:String):void{
			this.groupName = groupName;
			this.animName = animName;
			this.animData = BitmapClipFactory.Instance.getBitmapClipData(groupName);
			this.totalFrame = (this.animData.clipConfig[animName] as ClipData).totalFrames;
			if ( this.bitmapData == null ){
				this.bitmapData = new BitmapData(300, 200);
			}
		}
		
		private function onAdded(evt:Event):void{
			FrameMgr.Instance.add(this.frameItem);
		}
		
		private function onRemoved(evt:Event):void{
			FrameMgr.Instance.remove(this.frameItem.name);
		}
		
		private function draw():void{
			this.animData.render(this);
		}
		
		public function pause():void{
			FrameMgr.Instance.remove(this.name);
		}
		
		public function resume():void{
			FrameMgr.Instance.add(this.frameItem);
		}

		/**
		 * @param times total play times, -1 means nonstop
		 * @param autoRemove remove or not when play over
		 * @param onComplete call when play complete
		 * 
		 * **/
		public function play( times:int = -1, autoRemove:Boolean = true, onComplete:Function = null) :void {
			this.onComplete = onComplete;
			this.currentFrame = 0;
			this.currentAdvanceTime = 0;
			this.totalPlayTimes = times;
			this.currentPlayTimes = 0;
			this.autoRemove = autoRemove;
			this.draw();
		}
		
		private function nextFrame():void{
			this.currentFrame++;
			if ( this.currentFrame >= this.totalFrame ){//max frame
				if ( this.totalPlayTimes != -1){//limit play times
					this.totalPlayTimes--;
					this.currentFrame = 0;
					if ( this.totalPlayTimes == 0 ){//end times
						if ( this.onComplete != null ){
							this.onComplete();
						}
						if ( this.autoRemove && this.parent ){
							this.parent.removeChild(this);
						}
						return;
					}
				}
			}
			draw();
		}
		
		private var autoRemove:Boolean;
		private var onComplete:Function;
		public var currentFrame:uint;/** 0 - totalFrame - 1**/
		public var totalFrame:uint;
		private var currentPlayTimes:uint;
		private var totalPlayTimes:uint;
		private var currentAdvanceTime:uint = 0;
		public function advanceTime(delta:int):void{
			this.currentAdvanceTime+= delta;
			if ( this.currentAdvanceTime >= this.animGap ){
				this.nextFrame();
				this.currentAdvanceTime = 0;
			}
		}
		
		private var _fps:uint = 24;
		private var animGap:uint = 1000 / 24;
		public function set fps(value:uint):void{
			if ( this._fps == value ) return;
			this._fps = value;
			this.animGap = 1000 / value;
		}
		public function get fps():uint{
			return this._fps;
		}
	}

}